Angular Services and Providers

We provide services so that the dependency injection can inject them when needed. By best practice, we name services to be provided with the word “Service”, ex SalaryService. A service is simply a class. Note that services have the “@Injectable” decorator.

import { Injectable } from '@angular/core';

@Injectable()
export class SalaryService {
    getSalaries() {
        return [];
    }
}

If we want this service available to all components in a module, we import it in the module decorator under the “providers” property.

  providers: [
    DataService,
    SalaryService
  ],

If we want this service to only be available to a specific component, then we add in the component’s metadata.

import { SalaryService } from './salary.service';

@Component({
 ...
 providers: [
   SalaryService
 ],
 ...
})
export class MyComponent {
...
}

 

Dependency Injection

Angular’s dependency injection system is hierarchical. DI can happen at module levels or component levels. Note that when a service is injected at a module level, there is only a single instance of that service. And it becomes available to all components and child components of those components underneath this module.

If a service is injected in a single component, then only that component and those child components can access that service. Again there is only one instance of this service for those components.

In the case that a service is injected at both the module and a component, then there are two instances of the service. Here is where it can get tricky. For those components that reference the service, it will take the first instance it can find. So if that instance comes from a parent component, it will take that one. Else it will go all the way up to the module level and take it’s instance.

 

At the component level, a service is injected through the constructor. It should be saved to a property of that component.

...
export class MyComponent {
  constructor(private service: SalarayService) {}
}

Note that in the example above, by setting an access modifier to the service variable, TypeScript will set it as a local variable accessible throughout the component.

At the module level, the service can be provided to all components by the following syntax. Note that both syntax are identical.

@NgModule({
 ...
 providers: [ 
  SalaryService
 ],
 ..
})
---------------------------
 providers: [
  { provide: SalaryService, useClass: SalaryService
 ]